package cn.rxyb.core.calculate;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * @author YJH
 * @version 1.0
 * @description double计算
 * @date 2020/6/26 15:43
 */
public class DoubleCalculate implements NumberUtil {

    private static final DoubleCalculate instance = new DoubleCalculate();

    private DoubleCalculate() {
    }

    public static DoubleCalculate getInstance() {
        return instance;
    }


    /**
     * 小数点截取位置
     *
     * @param v1    数
     * @param scale 舍去小数点得位置
     * @return
     */
    public double scale(double v1, int scale) {
        return new BigDecimal(v1).setScale(scale, RoundingMode.HALF_UP).doubleValue();
    }


    /**
     * 小数点截取位置
     *
     * @param v1           数
     * @param scale        舍去小数点得位置
     * @param roundingMode 保留小数的模式
     * @return
     */
    public double scale(double v1, int scale, RoundingMode roundingMode) {
        return new BigDecimal(v1).setScale(scale, roundingMode).doubleValue();
    }

    /**
     * 提供精确的加法运算
     *
     * @param v1 数
     * @param v2 数
     * @return 和
     */
    public double add(float v1, float v2) {
        return add(Float.toString(v1), Float.toString(v2)).doubleValue();
    }

    /**
     * 提供精确的加法运算
     *
     * @param v1    被加数
     * @param v2    加数
     * @param scale 舍去小数点得位置
     * @return 和
     */
    public double add(float v1, float v2, int scale) {
        return add(Float.toString(v1), Float.toString(v2)).setScale(scale, RoundingMode.HALF_UP).doubleValue();
    }


    /**
     * 提供精确的加法运算
     *
     * @param v1           数
     * @param v2           数
     * @param scale        舍去小数点得位置
     * @param roundingMode 保留小数的模式
     * @return 和
     */
    public double add(float v1, float v2, int scale, RoundingMode roundingMode) {
        return add(Float.toString(v1), Float.toString(v2)).setScale(scale, roundingMode).doubleValue();
    }


    /**
     * 提供精确的加法运算
     *
     * @param v1 数
     * @param v2 数
     * @return 和
     */
    public double add(Float v1, double v2) {
        return add(Float.toString(v1), Double.toString(v2)).doubleValue();
    }

    /**
     * 提供精确的加法运算
     *
     * @param v1    数
     * @param v2    数
     * @param scale 保留小数点得位置
     * @return 和
     */
    public double add(Float v1, double v2, int scale) {
        return add(Float.toString(v1), Double.toString(v2)).setScale(scale, RoundingMode.HALF_UP).doubleValue();
    }


    /**
     * 提供精确的加法运算
     *
     * @param v1           数
     * @param v2           数
     * @param scale        保留小数点得位置
     * @param roundingMode 保留小数的模式
     * @return 和
     */
    public double add(Float v1, double v2, int scale, RoundingMode roundingMode) {
        return add(Float.toString(v1), Double.toString(v2)).setScale(scale, roundingMode).doubleValue();
    }


    /**
     * 提供精确的加法运算
     *
     * @param v1 数
     * @param v2 数
     * @return 和
     */
    public double add(double v1, double v2) {
        return add(Double.toString(v1), Double.toString(v2)).doubleValue();
    }

    /**
     * 提供精确的加法运算
     *
     * @param v1    被加数
     * @param v2    加数
     * @param scale 保留小数点得位置
     * @return 和
     */
    public double add(double v1, double v2, int scale) {
        return add(Double.toString(v1), Double.toString(v2)).setScale(scale, RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * 提供精确的加法运算
     *
     * @param v1           数
     * @param v2           数
     * @param scale        保留小数点得位置
     * @param roundingMode 保留小数的模式
     * @return 和
     */
    public double add(double v1, double v2, int scale, RoundingMode roundingMode) {
        return add(Double.toString(v1), Double.toString(v2)).setScale(scale, roundingMode).doubleValue();
    }


    /**
     * 提供精确的减法法运算
     *
     * @param v1 数
     * @param v2 数
     * @return
     */
    public double subtract(float v1, float v2) {
        return subtract(Float.toString(v1), Float.toString(v2)).doubleValue();
    }

    /**
     * 提供精确的减法运算
     *
     * @param v1    数
     * @param v2    数
     * @param scale 舍去小数点得位置
     * @return
     */
    public double subtract(float v1, float v2, int scale) {
        return subtract(Float.toString(v1), Float.toString(v2)).setScale(scale, RoundingMode.HALF_UP).doubleValue();
    }


    /**
     * 提供精确的减法法运算
     *
     * @param v1           数
     * @param v2           数
     * @param scale        舍去小数点得位置
     * @param roundingMode 保留小数的模式
     * @return 和
     */
    public double subtract(float v1, float v2, int scale, RoundingMode roundingMode) {
        return subtract(Float.toString(v1), Float.toString(v2)).setScale(scale, roundingMode).doubleValue();
    }


    /**
     * 提供精确的减法法运算
     *
     * @param v1 数
     * @param v2 数
     * @return 和
     */
    public double subtract(Float v1, double v2) {
        return subtract(Float.toString(v1), Double.toString(v2)).doubleValue();
    }

    /**
     * 提供精确的减法法运算
     *
     * @param v1    数
     * @param v2    数
     * @param scale 保留小数点得位置
     * @return 和
     */
    public double subtract(Float v1, double v2, int scale) {
        return subtract(Float.toString(v1), Double.toString(v2)).setScale(scale, RoundingMode.HALF_UP).doubleValue();
    }


    /**
     * 提供精确的减法法运算
     *
     * @param v1           数
     * @param v2           数
     * @param scale        保留小数点得位置
     * @param roundingMode 保留小数的模式
     * @return 和
     */
    public double subtract(Float v1, double v2, int scale, RoundingMode roundingMode) {
        return subtract(Float.toString(v1), Double.toString(v2)).setScale(scale, roundingMode).doubleValue();
    }


    /**
     * 提供精确的减法法运算
     *
     * @param v1 数
     * @param v2 数
     * @return 和
     */
    public double subtract(double v1, double v2) {
        return subtract(Double.toString(v1), Double.toString(v2)).doubleValue();
    }

    /**
     * 提供精确的减法法运算
     *
     * @param v1    数
     * @param v2    数
     * @param scale 保留小数点得位置
     * @return
     */
    public double subtract(double v1, double v2, int scale) {
        return subtract(Double.toString(v1), Double.toString(v2)).setScale(scale, RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * 提供精确的减法法运算
     *
     * @param v1           数
     * @param v2           数
     * @param scale        保留小数点得位置
     * @param roundingMode 保留小数的模式
     * @return
     */
    public double subtract(double v1, double v2, int scale, RoundingMode roundingMode) {
        return subtract(Double.toString(v1), Double.toString(v2)).setScale(scale, roundingMode).doubleValue();
    }

    /**
     * 提供精确的乘法运算
     *
     * @param v1 数
     * @param v2 数
     * @return
     */
    public double multiply(float v1, float v2) {
        return multiply(Float.toString(v1), Float.toString(v2)).doubleValue();
    }

    /**
     * 提供精确的乘法运算
     *
     * @param v1    被加数
     * @param v2    加数
     * @param scale 舍去小数点得位置
     * @return
     */
    public double multiply(float v1, float v2, int scale) {
        return multiply(Float.toString(v1), Float.toString(v2)).setScale(scale, RoundingMode.HALF_UP).doubleValue();
    }


    /**
     * 提供精确的乘法运算
     *
     * @param v1           数
     * @param v2           数
     * @param scale        舍去小数点得位置
     * @param roundingMode 保留小数的模式
     * @return
     */
    public double multiply(float v1, float v2, int scale, RoundingMode roundingMode) {
        return multiply(Float.toString(v1), Float.toString(v2)).setScale(scale, roundingMode).doubleValue();
    }


    /**
     * 提供精确的乘法运算
     *
     * @param v1 数
     * @param v2 数
     * @return
     */
    public double multiply(Float v1, double v2) {
        return multiply(Float.toString(v1), Double.toString(v2)).doubleValue();
    }

    /**
     * 提供精确的乘法运算
     *
     * @param v1    数
     * @param v2    数
     * @param scale 保留小数点得位置
     * @return
     */
    public double multiply(Float v1, double v2, int scale) {
        return multiply(Float.toString(v1), Double.toString(v2)).setScale(scale, RoundingMode.HALF_UP).doubleValue();
    }


    /**
     * 提供精确的乘法运算
     *
     * @param v1           数
     * @param v2           数
     * @param scale        保留小数点得位置
     * @param roundingMode 保留小数的模式
     * @return
     */
    public double multiply(Float v1, double v2, int scale, RoundingMode roundingMode) {
        return multiply(Float.toString(v1), Double.toString(v2)).setScale(scale, roundingMode).doubleValue();
    }


    /**
     * 提供精确的乘法运算
     *
     * @param v1 数
     * @param v2 数
     * @return
     */
    public double multiply(double v1, double v2) {
        return multiply(Double.toString(v1), Double.toString(v2)).doubleValue();
    }

    /**
     * 提供精确的乘法运算
     *
     * @param v1    被加数
     * @param v2    加数
     * @param scale 保留小数点得位置
     * @return
     */
    public double multiply(double v1, double v2, int scale) {
        return multiply(Double.toString(v1), Double.toString(v2)).setScale(scale, RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * 提供精确的乘法运算
     *
     * @param v1           数
     * @param v2           数
     * @param scale        保留小数点得位置
     * @param roundingMode 保留小数的模式
     * @return
     */
    public double multiply(double v1, double v2, int scale, RoundingMode roundingMode) {
        return multiply(Double.toString(v1), Double.toString(v2)).setScale(scale, roundingMode).doubleValue();
    }


    /**
     * 提供精确的除法运算
     *
     * @param v1 数
     * @param v2 数
     * @return
     */
    public double divide(float v1, float v2) {
        return divide(Float.toString(v1), Float.toString(v2)).doubleValue();
    }

    /**
     * 提供精确的除法运算
     *
     * @param v1    被加数
     * @param v2    加数
     * @param scale 舍去小数点得位置
     * @return
     */
    public double divide(float v1, float v2, int scale) {
        return divide(Float.toString(v1), Float.toString(v2)).setScale(scale, RoundingMode.HALF_UP).doubleValue();
    }


    /**
     * 提供精确的除法运算
     *
     * @param v1           数
     * @param v2           数
     * @param scale        舍去小数点得位置
     * @param roundingMode 保留小数的模式
     * @return
     */
    public double divide(float v1, float v2, int scale, RoundingMode roundingMode) {
        return divide(Float.toString(v1), Float.toString(v2)).setScale(scale, roundingMode).doubleValue();
    }


    /**
     * 提供精确的除法运算
     *
     * @param v1 数
     * @param v2 数
     * @return
     */
    public double divide(Float v1, double v2) {
        return divide(Float.toString(v1), Double.toString(v2)).doubleValue();
    }

    /**
     * 提供精确的除法运算
     *
     * @param v1    数
     * @param v2    数
     * @param scale 保留小数点得位置
     * @return
     */
    public double divide(Float v1, double v2, int scale) {
        return divide(Float.toString(v1), Double.toString(v2)).setScale(scale, RoundingMode.HALF_UP).doubleValue();
    }


    /**
     * 提供精确的除法运算
     *
     * @param v1           数
     * @param v2           数
     * @param scale        保留小数点得位置
     * @param roundingMode 保留小数的模式
     * @return
     */
    public double divide(Float v1, double v2, int scale, RoundingMode roundingMode) {
        return divide(Float.toString(v1), Double.toString(v2)).setScale(scale, roundingMode).doubleValue();
    }


    /**
     * 提供精确的除法运算
     *
     * @param v1 数
     * @param v2 数
     * @return
     */
    public double divide(double v1, double v2) {
        return divide(Double.toString(v1), Double.toString(v2)).doubleValue();
    }

    /**
     * 提供精确的除法运算
     *
     * @param v1    被加数
     * @param v2    加数
     * @param scale 保留小数点得位置
     * @return
     */
    public double divide(double v1, double v2, int scale) {
        return divide(Double.toString(v1), Double.toString(v2)).setScale(scale, RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * 提供精确的除法运算
     *
     * @param v1           数
     * @param v2           数
     * @param scale        保留小数点得位置
     * @param roundingMode 保留小数的模式
     * @return
     */
    public double divide(double v1, double v2, int scale, RoundingMode roundingMode) {
        return divide(Double.toString(v1), Double.toString(v2)).setScale(scale, roundingMode).doubleValue();
    }
}
